home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / cpp_libs / cool / cool.lha / ice / pisces / mkdepend / include.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-04  |  6.0 KB  |  285 lines

  1. /*
  2.  * $XConsortium: include.c,v 1.7 88/11/08 12:19:55 jim Exp $
  3.  */
  4. #include "def.h"
  5.  
  6. extern struct    inclist    inclist[ MAXFILES ],
  7.             *inclistp;
  8. extern char    *includedirs[ ];
  9. extern char    *notdotdot[ ];
  10. extern boolean show_where_not;
  11. extern char path_sep;
  12.  
  13. struct inclist *inc_path(file, include, dot)
  14.     register char    *file,
  15.             *include;
  16.     boolean    dot;
  17. {
  18.     static char    path[ BUFSIZ ];
  19.     register char        **pp, *p;
  20.     register struct inclist    *ip;
  21.     struct stat    st;
  22.     boolean    found = FALSE;
  23.  
  24.     /*
  25.      * Check all previously found include files for a path that
  26.      * has already been expanded.
  27.      */
  28.     for (ip = inclist; ip->i_file; ip++)
  29.         if ((strcmp(ip->i_incstring, include) == 0) && !ip->i_included_sym)
  30.         {
  31.         found = TRUE;
  32.         break;
  33.         }
  34.  
  35.     /*
  36.      * If the path was surrounded by "", then check the absolute
  37.      * path provided.
  38.      */
  39.     if (!found && dot) {
  40.         if (stat(include, &st) == 0) {
  41.             ip = newinclude(include, include);
  42.             found = TRUE;
  43.         }
  44.         else if (show_where_not)
  45.             do_log("\tnot in %s\n", include);
  46.     }
  47.  
  48.     /*
  49.      * See if this include file is in the directory of the
  50.      * file being compiled.
  51.      */
  52.     if (!found) {
  53.         for (p=file+strlen(file); p>file; p--)
  54.             if (*p == path_sep)
  55.                 break;
  56.         if (p == file)
  57.             strcpy(path, include);
  58.         else {
  59.             strncpy(path, file, (p-file) + 1);
  60.             path[ (p-file) + 1 ] = '\0';
  61.             strcpy(path + (p-file) + 1, include);
  62.         }
  63.         remove_dotdot(path);
  64.         if (stat(path, &st) == 0) {
  65.             ip = newinclude(path, include);
  66.             found = TRUE;
  67.         }
  68.         else if (show_where_not)
  69.             do_log("\tnot in %s\n", path);
  70.     }
  71.  
  72.     /*
  73.      * Check the include directories specified. (standard include dir
  74.      * should be at the end.)
  75.      */
  76.     if (!found)
  77.         for (pp = includedirs; *pp; pp++) {
  78. #ifdef VMS
  79.             sprintf(path, "%s%s", *pp, include);
  80. #else
  81. #ifdef os2
  82.             sprintf(path, "%s\\%s", *pp, include);
  83. #else
  84.             sprintf(path, "%s/%s", *pp, include);
  85. #endif
  86. #endif
  87.             remove_dotdot(path);
  88.             if (stat(path, &st) == 0) {
  89.                 ip = newinclude(path, include);
  90.                 found = TRUE;
  91.                 break;
  92.             }
  93.             else if (show_where_not)
  94.                 do_log("\tnot in %s\n", path);
  95.         }
  96.  
  97.     if (!found) {
  98.         /*
  99.          * If we've announced where it's not include it anyway so
  100.          * it gets on the dependency list.
  101.          */
  102.         if (show_where_not)
  103.             ip = newinclude(include, include);
  104.         else
  105.             ip = NULL;
  106.     }
  107.     return(ip);
  108. }
  109.  
  110. /*
  111.  * Ocaisionally, pathnames are created that look like ../x/../y
  112.  * Any of the 'x/..' sequences within the name can be eliminated.
  113.  * (but only if 'x' is not a symbolic link!!)
  114.  */
  115. remove_dotdot(path)
  116.     char    *path;
  117. {
  118.     register char    *end, *from, *to, **cp;
  119.     char        *components[ MAXFILES ],
  120.             newpath[ BUFSIZ ];
  121.     boolean        component_copied;
  122.  
  123.     /*
  124.      * slice path up into components.
  125.      */
  126.     to = newpath;
  127.     if (*path == path_sep)
  128.         *to++ = path_sep;
  129.     *to = '\0';
  130.     cp = components;
  131.     for (from=end=path; *end; end++)
  132.         if (*end == path_sep) {
  133.             while (*end == path_sep)
  134.                 *end++ = '\0';
  135.             if (*from)
  136.                 *cp++ = from;
  137.             from = end;
  138.         }
  139.     *cp++ = from;
  140.     *cp = NULL;
  141.  
  142.     /*
  143.      * Now copy the path, removing all 'x/..' components.
  144.      */
  145.     cp = components;
  146.     component_copied = FALSE;
  147.     while(*cp) {
  148.         if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))) {
  149.             if (issymbolic(newpath, *cp))
  150.                 goto dont_remove;
  151.             cp++;
  152.         } else {
  153.         dont_remove:
  154.             if (component_copied)
  155.                 *to++ = path_sep;
  156.             component_copied = TRUE;
  157.             for (from = *cp; *from; )
  158.                 *to++ = *from++;
  159.             *to = '\0';
  160.         }
  161.         cp++;
  162.     }
  163.     *to++ = '\0';
  164.  
  165.     /*
  166.      * copy the reconstituted path back to our pointer.
  167.      */
  168.     strcpy(path, newpath);
  169. }
  170.  
  171. isdot(p)
  172.     register char    *p;
  173. {
  174.     if(p && *p++ == '.' && *p++ == '\0')
  175.         return(TRUE);
  176.     return(FALSE);
  177. }
  178.  
  179. isdotdot(p)
  180.     register char    *p;
  181. {
  182.     if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
  183.         return(TRUE);
  184.     return(FALSE);
  185. }
  186.  
  187. issymbolic(dir, component)
  188.     register char    *dir, *component;
  189. {
  190. #ifdef S_IFLNK
  191.     struct stat    st;
  192.     char    buf[ BUFSIZ ], **pp;
  193.  
  194.     sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
  195.     for (pp=notdotdot; *pp; pp++)
  196.         if (strcmp(*pp, buf) == 0)
  197.             return (TRUE);
  198.     if (lstat(buf, &st) == 0
  199.     && (st.st_mode & S_IFMT) == S_IFLNK) {
  200.         *pp++ = copy(buf);
  201.         if (pp >= ¬dotdot[ MAXDIRS ])
  202.             log_fatal("out of .. dirs, increase MAXDIRS\n");
  203.         return(TRUE);
  204.     }
  205. #endif
  206.     return(FALSE);
  207. }
  208.  
  209. /*
  210.  * Add an include file to the list of those included by 'file'.
  211.  */
  212. struct inclist *newinclude(newfile, incstring)
  213.     register char    *newfile, *incstring;
  214. {
  215.     register struct inclist    *ip;
  216.  
  217.     /*
  218.      * First, put this file on the global list of include files.
  219.      */
  220.     ip = inclistp++;
  221.     if (inclistp == inclist + MAXFILES - 1)
  222.         log_fatal("out of space: increase MAXFILES\n");
  223.     ip->i_file = copy(newfile);
  224.     ip->i_included_sym = FALSE;
  225.     if (incstring == NULL)
  226.         ip->i_incstring = ip->i_file;
  227.     else
  228.         ip->i_incstring = copy(incstring);
  229.  
  230.     return(ip);
  231. }
  232.  
  233. void
  234. included_by(ip, newfile)
  235.     register struct inclist    *ip, *newfile;
  236. {
  237.     register i;
  238.  
  239.     if (ip == NULL)
  240.         return;
  241.     /*
  242.      * Put this include file (newfile) on the list of files included
  243.      * by 'file'.  If 'file' is NULL, then it is not an include
  244.      * file itself (i.e. was probably mentioned on the command line).
  245.      * If it is already on the list, don't stick it on again.
  246.      */
  247.     if (ip->i_list == NULL)
  248.         ip->i_list = (struct inclist **)
  249.             malloc(sizeof(struct inclist *) * ++ip->i_listlen);
  250.     else {
  251.         for (i=0; i<ip->i_listlen; i++)
  252.             if (ip->i_list[ i ] == newfile) {
  253.                 if (!ip->i_included_sym)
  254.                 {
  255.                 /* only bitch if ip has */
  256.                 /* no #include SYMBOL lines  */
  257.                 
  258. /**
  259.  ** The log messages for multiply included files seems inappropriate now that
  260.  ** mkdepend generates dependencies for .[hcC] files instead of .o files. Thus
  261.  ** I'm commenting this stuff out for now -- MBN
  262.  **
  263.  **                log("%s includes %s more than once!\n",
  264.  **                    ip->i_file, newfile->i_file);
  265.  **                log("Already have\n");
  266.  **                for (i=0; i<ip->i_listlen; i++)
  267.  **                    log("\t%s\n", ip->i_list[i]->i_file);
  268.  **/                }
  269.                 return;
  270.             }
  271.         ip->i_list = (struct inclist **) realloc(ip->i_list,
  272.             sizeof(struct inclist *) * ++ip->i_listlen);
  273.     }
  274.     ip->i_list[ ip->i_listlen-1 ] = newfile;
  275. }
  276.  
  277. inc_clean ()
  278. {
  279.     register struct inclist *ip;
  280.  
  281.     for (ip = inclist; ip < inclistp; ip++) {
  282.         ip->i_marked = FALSE;
  283.     }
  284. }
  285.